<?php

namespace app\service;

use think\Cache;

class SeckillService
{

    // 在服务层添加本地缓存
    private static $localStock = [];

    public static function getStock($goodsId)
    {
        if (!isset(self::$localStock[$goodsId])) {
            $redis = Cache::store('redis')->handler();
            self::$localStock[$goodsId] = $redis->get("stock:goods:{$goodsId}");
        }
        return self::$localStock[$goodsId];
    }

    // 初始化商品库存
    public static function initStock($goodsId, $stock)
    {
        $redis = Cache::store('redis')->handler();
        $key = "stock:goods:{$goodsId}";
        $redis->set($key, $stock);
    }

    // 执行秒杀下单
    public static function doSeckill($userId, $goodsId)
    {
        $redis = Cache::store('redis')->handler();
        $stockKey = "stock:goods:{$goodsId}";
        $userSetKey = "user:ordered:{$goodsId}";

        // 1. 检查用户是否已经下单
        if ($redis->sIsMember($userSetKey, $userId)) {
            return ['success' => false, 'msg' => '您已经参与过秒杀'];
        }

        // 2. 检查库存
        $stock = $redis->get($stockKey);
        if ($stock <= 0) {
            return ['success' => false, 'msg' => '商品已售罄'];
        }

        // 使用分布式锁保证原子操作
        return LockService::safeExecute($stockKey,function () use ($redis,$userId,$goodsId,$stockKey,$userSetKey){

            // 再次检查库存（双检）
            $currentStock  = $redis->get($stockKey);
            if ($currentStock  <= 0) {
                return ['success' => false, 'msg' => '商品已售罄'];
            }

            // 3. 使用原子操作扣减库存
            $redis->decr($stockKey);

            // 4. 标记用户已下单
            $redis->sAdd($userSetKey, $userId);

            // 5. 生成订单数据
            $orderData = [
                'user_id' => $userId,
                'goods_id' => $goodsId,
                'price' => self::getSeckillPrice($goodsId),
                'create_time' => time()
            ];

            // 6. 订单入队（异步处理）
            $redis->lPush('order:queue', json_encode($orderData));

            return ['success' => true, 'msg' => '秒杀成功，请尽快支付'];
        },3);// 锁超时3秒
    }

    // 获取秒杀价格（简化版）
    private static function getSeckillPrice($goodsId)
    {
        // 实际项目中从数据库获取
        return db('goods')->where('id',$goodsId)->value('seckill_price');
    }
}